import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;

/**
 * @description:
 * @title: GcRootsDemo
 * @author: zp
 * @date: 2021/8/8 15:55
 * GCRoots 对象的分类
 * 1、虚拟机栈（栈帧中的本地变量表）中引用的对象
 * 2、方法区中的类静态属性引用的对象
 * 3、方法区中常量引用的对象
 * 4、本地方法栈中JNI （即一般说的native 方法）中的引用对象
 * JVM参数的类型
 * 1、标准参数
 * 2、x类型参数
 * 3、xx类型参数
 * 1、布尔类型
 * -XX:+ 代表开启
 * -XX:- 代表关闭
 * 查看方式：使用jps -l 查看相关进程
 * 使用jinfo 使用 jinfo -flag（如果是这个flags 后面拼接多个参数） 需要查看的参数名称（比如PrintGCDetails 不传入则打印所以参数） 进程编号
 * 2、KV设值类型
 * -XX:属性Key=属性Value
 * 查看jvm启动参数配置 java -XX:+PrintFlagsInitial
 * 查看jvm已经被修改后的参数（在参数后面有:） java -XX:+PrintFlagsFinal -version
 * 查看jvm已经被修改后的单个参数（在参数后面有:） java -XX:+PrintFlagsFinal 参数设置值 如：-XX:MetaspaceSize = 512MB
 * 查看jvm启动常用参数配置 java -XX:+PrintCommandLineFlags -version
 * <p>
 * 引用分类
 * 1、强引用（Reference） 永不回收
 * 2、软引用 （SoftReference） 内存够用 不回收 内存不够用回收
 * 3、弱引用（WeakReference） 发生GC就会回收
 * WeakHashMap:弱引用的HashMap 在发生GC时 会被回收
 * 4、虚引用（PhantomReference）发生GC就会回收 要联合引用队列（ReferenceQueue）使用
 * 引用队列：在对象被回收之后 都会放到引用队列中 在回收的时候可以做一些操作 相当于一种消息通知机制
 */
public class GcRootsDemo {
    private byte[] bytes = new byte[1024 * 100 * 1024];


    public static void main(String[] args) {
        //m1();
        for (int i = 0; i < 2000; i++) {
            new Thread(() -> {
                System.out.println("等待");
                try {
                    Thread.sleep(Integer.MAX_VALUE);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }, "线程" + i).start();
        }
    }

    public static void m1() {
        //虚引用（PhantomReference）发生GC就会回收 要联合引用队列（ReferenceQueue）使用
        Object o1 = new Object();
        ReferenceQueue<Object> referenceReferenceQueue = new ReferenceQueue<>();
        PhantomReference phantomReference = new PhantomReference(o1, referenceReferenceQueue);
        System.out.println(o1);
        System.out.println(phantomReference.get());
        System.out.println(referenceReferenceQueue.poll());

        System.out.println("==========");

        o1 = null;
        System.gc();
        System.out.println(o1);
        System.out.println(phantomReference.get());
        System.out.println(referenceReferenceQueue.poll());
    }
}
